<?php


namespace app\shop\controller\api;


use app\shop\common\consts\Consts;
use app\shop\common\consts\ErrorCode;
use app\shop\common\consts\SmsCode;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\model\config\ConfigModel;
use app\BaseController;
use app\shop\service\config\ConfigService;
use app\shop\service\until\CaptchaService;
use app\shop\model\config\ArticleModel;
use app\shop\service\until\SmsService;
use app\shop\service\until\FileService;
use app\shop\service\user\FriendService;
use app\shop\service\user\UserService;
use app\shop\validate\UserValidate;
use GatewayClient\Gateway;
use think\App;
use think\facade\Log;

class UserController extends BaseController
{

    public function __construct(App $app)
    {
        Gateway::$registerAddress = config('gateway.registerAddress');
        parent::__construct($app);
    }

    /**
     * 用户信息查询
     * @return \think\response\Json
     */
    public function getUserInfo()
    {
        try {
            $userInfo = $this->request->middleware('userInfo');
            $onlineInfo = UserService::getUserOnlineStatus($userInfo['user_id'], $userInfo);
            $data = [
                'user_id' => $userInfo['user_id'],
                'mobile' => $userInfo['mobile'],
                'realname' => $userInfo['realname'],
                'role_id' => $userInfo['role_id'],
                'department_id' => $userInfo['department_id'],
                'avatar' => $userInfo['avatar'],
                'score' => $userInfo['score'],
                'worker_score' => $userInfo['worker_score'],
                'create_time' => $userInfo['create_time'],
                'app_token' => $userInfo['app_token'],
                'pc_token' => $userInfo['pc_token'],
                'login_status' => $onlineInfo['login_status'],
                'morning_start_work_time' => $userInfo['morning_start_work_time'],
                'afternoon_end_work_time' => $userInfo['afternoon_end_work_time'],
                'auto_reply' => $userInfo['auto_reply'],
                'online' => $onlineInfo['online'],
            ];
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }


    /**
     * 设置用户昵称，手机号
     * @return \think\response\Json
     */
    public function setUserInfo()
    {
        try {
            $realName = $this->request->param('realname', '', 'trim');
            $mobile = $this->request->param('mobile', '', 'trim');
            $userInfo = $this->request->middleware('userInfo');

            $mobile = $mobile ? $mobile : $userInfo['mobile'];
            $realName = $realName ? $realName : $userInfo['realname'];

            if (mb_strlen($realName) > 15) {
                throw new \Exception('昵称长度不能超过15个字符');
            }

//            if (!isPhoneNumber($mobile)) {
//                throw new \Exception('手机号格式错误');
//            }
//
//            if ($mobile != $userInfo['mobile'] && UserModel::getByMobile($mobile)) {
//                throw new \Exception('手机号已存在');
//            }

//            $userInfo->mobile = $mobile;
            $userInfo->realname = $realName;
            $userInfo->save();
            return $this->success("上传成功");
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    //密码修改
    public function setPassword()
    {
        try {
            $mobile = $this->request->param('mobile', '', 'trim');
            $pwd = $this->request->param('password', '', 'trim');
            $pwdConfirm = $this->request->param('password_confirm', '', 'trim');
            $userInfo = $this->request->middleware('userInfo');
            // 判断手机号是否为空
            if (empty($mobile)) {
                throw new \Exception("手机号不能为空");
            }
            // 判断输入的手机号与当前用户的手机号是否一致
            if ($mobile !== $userInfo->mobile) {
                throw new \Exception("账号错误");
            }
            // 判断两次输入的密码是否一致
            if ($pwd !== $pwdConfirm) {
                throw new \Exception("两次输入的密码不一致");
            }
            if ($pwd) {
                $userInfo->password = password_hash($pwd . $userInfo->salt, PASSWORD_DEFAULT);
            }
            $userInfo->save();
            return $this->success('密码修改成功');
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 发送短信
     * @return \think\response\Json
     */
    public function sendSms()
    {
        try {
            $mobile = $this->request->param('mobile', '', 'trim');
            $type = $this->request->param('type', '', 'trim');
            SmsService::sendSms($mobile, $type);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 生成验证码
     * @return \think\response\Json
     */
    public function createCaptcha()
    {
        try {
            $data = CaptchaService::createCaptcha();
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 注册
     * @return \think\response\Json
     */
    public function register()
    {
        try {
            $data = $this->request->only(['mobile', 'password', 'realname', 'password_confirm', 'sms_code']);

            Validate(UserValidate::class)->scene('apiRegister')->check($data);

            SmsService::verifySms($data['mobile'], $data['sms_code'], SmsCode::APP_REGISTER);

            // 使用模型查询用户信息
            $userInfo = UserModel::where('mobile', $data['mobile'])->find();
            if ($userInfo) {
                throw new \Exception('手机号已被占用');
            }

            $data['user_sn'] = random(6, 'letter');
            $data['realname'] = '用户' . $data['user_sn'];
            $data['salt'] = random(4);
            $data['password'] = password_hash($data['password'] . $data['salt'], PASSWORD_DEFAULT);
            $configInfo = ConfigService::getConfigValue('sysInfo');
            $ossUrl = getDiskUrl();
            $avatar = '';
            if (strpos($configInfo['customer_avatar'], $ossUrl) !== false) {
                $avatar = str_replace($ossUrl, '', $configInfo['customer_avatar']);
            }
            $data['avatar'] = $avatar;
            $user = new UserModel();
            $user->save($data);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 登录
     * @return \think\response\Json
     */
    public function login()
    {
        try {
            $data = $this->request->only(['mobile', 'password', 'sms_code', 'img_code', 'login_type', 'uniqid']);

            Validate(UserValidate::class)->scene('apiLogin')->check($data);

            // 使用模型查询用户信息
            $userInfo = UserModel::where('mobile', $data['mobile'])->find();
            if (!$userInfo) {
                throw new \Exception('账号错误', ErrorCode::IMG_CODE_ERROR);
            }
            if (in_array($userInfo['role_id'], [Consts::DESIGN_LEADER_ID, Consts::DESIGN_ID])) {
                throw new \Exception('无登录权限', ErrorCode::IMG_CODE_ERROR);
            }

            // 图片验证码
            CaptchaService::verifyCaptcha($data['uniqid'] ?? '', $data['img_code']);

            if ($data['login_type'] == 1) {
                // 密码不匹配
                $password = $data['password'] ?? '';
                if (!password_verify($password . $userInfo->salt, $userInfo->password)) {
                    throw new \Exception('密码错误');
                }
            } else {
                SmsService::verifySms($data['mobile'], $data['sms_code'] ?? '', SmsCode::APP_LOGIN);
            }
            // 用户绑定的客户端下线
            UserService::userOffline($userInfo['user_id']);
            // 更新用户登录信息和生成token
            $token = 'APP|' . random(30, 'string');
            $info = [
                'last_login_time' => time(),
                'last_login_ip' => $this->request->ip(),
                'app_token' => $token,
                'login_status' => 1,
                'set_login_status' => 1,
                'app_token_valid_time' => time() + 86400,
            ];
            $userInfo->save($info);
            unset($userInfo['password'], $userInfo['salt'], $userInfo['status']);
            return $this->success($userInfo);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage(), [], ErrorCode::IMG_CODE_ERROR);
        }
    }

    /**
     * 客户端绑定用户ID
     * @return \think\response\Json
     */
    public function bindUid()
    {
        try {
//            $userId = $this->request->middleware('userId');
//            $userInfo = $this->request->middleware('userInfo');
//            $clientId = $this->request->param('client_id', '', 'trim');
//            if ($clientId == '') {
//                throw new \Exception('缺少客户端ID');
//            }
//            Gateway::bindUid($clientId, $userId);
//            $data = [
//                'type' => 'isOnline',
//                'time' => time(),
//                'data' => ['id' => $userId, 'is_online' => 1, 'login_status' => $userInfo['login_status'], 'route' => '/api/bindUid']
//            ];
//            Gateway::sendToAll(json_encode($data));
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 找回密码
     * @return \think\response\Json
     */
    public function retrieve()
    {
        try {
            $data = $this->request->only(['mobile', 'password', 'password_confirm', 'sms_code']);
            Validate(UserValidate::class)->scene('apiRetrieve')->check($data);
            // 查询用户信息
            $userInfo = UserModel::where('mobile', $data['mobile'])->find();
            if (!$userInfo) {
                throw new \Exception('该手机号未注册');
            }
            // 验证短信验证码
            SmsService::verifySms($data['mobile'], $data['sms_code'], SmsCode::APP_FORGOT_PWD);
            // 更新用户密码
            $salt = random(4); // 生成随机盐值
            $passwordHash = password_hash($data['password'] . $salt, PASSWORD_DEFAULT);
            // 更新用户数据
            $userInfo->salt = $salt;
            $userInfo->password = $passwordHash;
            $userInfo->save();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 退出登录
     * @return \think\response\Json
     */
    public function logout()
    {
        try {
            $user = UserModel::where('app_token', $this->request->header('Authorization'))->find();
            if (!$user) {
                throw new \Exception('用户未登录');
            }
            // 清除登录状态
            $user->app_token = null;
            $user->login_status = 0;
            $user->save();
            Gateway::$registerAddress = config('gateway.registerAddress');
            $clientArr = Gateway::getClientIdByUid($user['user_id']);
            foreach ($clientArr as $client) {
                Gateway::closeClient($client);
            }
            wsSendMsg(0, 'isOnline', ['id' => $user['user_id'], 'is_online' => 0, 'login_status' => 0]);
            return $this->success('退出登录成功');
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 获取用户协议
     * @return \think\response\Json
     */
    public function userAgreement()
    {
        try {
            $article = ConfigModel::where('id', ConfigModel::USER_AGREEMENT)->find();
            return $this->success($article);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 设置用户登录状态
     * @return \think\response\Json
     */
    public function setUserLoginStatus()
    {
        try {
            $status = $this->request->param('status', 0, 'int');
            $userId = $this->request->middleware('userId');
            $userInfo = $this->request->middleware('userInfo');
            if (in_array($status, [1, 2, 0])) {
                $userInfo->login_status = $status;
                $userInfo->set_login_status = $status;
                $userInfo->save();
            }
            $onlineInfo = UserService::getUserOnlineStatus($userId, $userInfo);
            $loginStatus = $onlineInfo['login_status'];
            $online = $onlineInfo['online'];
            $msg = [
                'type' => 'isOnline',
                'time' => time(),
                'data' => ['id' => $userId, 'is_online' => $online, 'login_status' => $loginStatus]
            ];
            Gateway::sendToAll(json_encode($msg));
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 获取某个用户的信息
     * @return \think\response\Json
     */
    public function getOtherUserInfo()
    {
        try {
            $uid = $this->request->param('user_id', 0, 'int');
            if (!$uid) {
                throw new \Exception('缺少用户ID');
            }
            $sign = $this->request->param('chat_sign', 0, 'trim');
            if (!$sign) {
                throw new \Exception('缺少聊天标识');
            }
            $userId = $this->request->middleware('userId');

            $userInfo = UserModel::find($uid);

            $unread = MessageModel::where('to_user', $userId)
                ->where('is_read', 0)
                ->where('is_group', 0)
                ->where('chat_sign', $sign)
                ->where('chat_status', 1)
                ->where('type', '<>', 'event')
                ->count('msg_id');
            $onlineInfo = UserService::getUserOnlineStatus($uid, $userInfo);
            $loginStatus = $onlineInfo['login_status'];
            $online = $onlineInfo['online'];
            $data = [
                'user_id' => $uid,
                'realname' => $userInfo['realname'],
                'avatar' => $userInfo['avatar'],
                'is_online' => $online,
                'login_status' => $loginStatus,
                'unread' => $unread,
            ];
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 设置自动回复
     * @return \think\response\Json
     */
    public function setAutoReply()
    {
        try {
            $userInfo = $this->request->middleware('userInfo');
            $content = $this->request->param('content', '', 'trim');
            $userInfo->auto_reply = $content;
            $userInfo->save();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 获取某个用户的信息
     * @return \think\response\Json
     */
    public function getUserLoginStatus()
    {
        try {
            $uid = $this->request->param('user_id', 0, 'int');
            if (!$uid) {
                throw new \Exception('缺少用户ID');
            }
            $userInfo = UserModel::find($uid);
            $onlineInfo = UserService::getUserOnlineStatus($uid, $userInfo);
            $loginStatus = $onlineInfo['login_status'];
            $online = $onlineInfo['online'];
            $data = [
                'user_id' => $uid,
                'realname' => $userInfo['realname'],
                'avatar' => $userInfo['avatar'],
                'is_online' => $online,
                'login_status' => $loginStatus,
            ];
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function writeOffUser()
    {
        try {
            $data = [
                'type' => 'write_off',
                'msg' => '24小时后注销成功'
            ];
            return $this->success($data);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }
}